#!/bin/bash -e
#   * compile instructions: put this file in
#   *         `steamapps/common/Dyson Sphere Program/CustomMod`
#   * folder, open a terminal in the same folder, and execute:
#   *
#   * ```
#   *     chmod +x powerFull.cs
#   *     ./powerFull.cs
#   * ```
#   *
#   * then the mod will be compiled automatically.
#   *
#   * Here we wrote a shebang like file, which is correct
#   * in my computer (Manjaro XFCE), if such script do not work
#   * in your computer, you could just try the instructions below :

export IFS=$'\n' # to disable the annoying space.
export DOTNET=dotnet # the location of the DOTNET executable file.
[ -z "$DOTNET_CSC_DLL" ] && export DOTNET_CSC_DLL=`\ls /usr/share/dotnet/sdk/*/Roslyn/bincore/csc.dll` # In manjaro, the csc.dll is located in /usr/share/dotnet/sdk/*/Roslyn/bincore/csc.dll

__MODE_VERBOSE=78 # is the line number of "#define VERBOSE", may be modified
__MODE_DEBUG__=$((__MODE_VERBOSE+1))
__MODE_RELEASE=$((__MODE_DEBUG__+1))

case $1 in
    V)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    v)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    VERBOSE) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    verbose) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    D)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    d)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    DEBUG)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    debug)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    *)       _MODE__SELECT_=$__MODE_RELEASE     ;;
esac

export GAME_BASE_DIR="common/B100X/B100X"
export FILE_NAME="$0"
export ASSEMBLY="Assembly-CSharp"
export PLUGIN_ID="Neutron3529.Cheat"
export NAMESPACE_ID="Neutron3529.Cheat"

( yes "" | head -n $_MODE__SELECT_ | head -n-1  ; tail $FILE_NAME -n+$_MODE__SELECT_ ) | sed s/%%NAMESPACE_ID%%/${NAMESPACE_ID}/g | sed s/%%PLUGIN_ID%%/${PLUGIN_ID}/g | $DOTNET $DOTNET_CSC_DLL -nologo -t:library \
  -r:"${GAME_BASE_DIR}/BepInEx/core/0Harmony.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.Core.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.IL2CPP.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/UnhollowerBaseLib.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/unhollowed/Il2Cppmscorlib.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/unhollowed/UnityEngine.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/unhollowed/UnityEngine.UI.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/unhollowed/UnityEngine.CoreModule.dll" \
  $(for i in "${GAME_BASE_DIR}/BepInEx/unhollowed/$ASSEMBLY"*.dll ; do echo -e "-r:\"$i\"\n" ; done) \
  `[ -e "${GAME_BASE_DIR}/mono/Managed/netstandard.dll" ] && echo "-r:\"${GAME_BASE_DIR}/mono/Managed/netstandard.dll\""` \
  -r:"${GAME_BASE_DIR}/mono/Managed/System.dll" \
  -r:"${GAME_BASE_DIR}/mono/Managed/System.Core.dll" \
  -r:"${GAME_BASE_DIR}/mono/Managed/mscorlib.dll" \
  -out:"${GAME_BASE_DIR}/BepInEx/plugins/${FILE_NAME%.*}".dll \
  -optimize `[ x"$_MODE__SELECT_" == x"$__MODE_DEBUG__" ] && echo -debug` \
  - && rm -f "${GAME_BASE_DIR}/BepInEx/config/${PLUGIN_ID}.cfg";

if [ -n "$2" ]; then
    git add ${FILE_NAME}
    case $2 in
        R) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        r) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        RANDOM) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        random) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        U) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        u) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        UPLOAD) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        upload) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        *) git commit -am "$2" ;;
    esac
    git push
fi
exit

#define VERBOSE // the line of __MODE_VERBOSE
#define DEBUG




using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;

using BepInEx;
using BepInEx.IL2CPP;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

namespace %%NAMESPACE_ID%%
{
    [BepInPlugin("%%PLUGIN_ID%%", "%%NAMESPACE_ID%%", "0.1.0")]
    public class Cheat : BasePlugin {
#if DEBUG
        public static Action<string> logger;
#else
        public static void logger(string s){}
#endif
        public override void Load() {
            var harmony=new Harmony("%%PLUGIN_ID%%");
#if DEBUG
            logger=Log.LogInfo;
#endif
            logger("叮~您的修改器已启动");
            harmony.PatchAll(typeof(NussygameCoreGainExp));
            harmony.PatchAll(typeof(AdventureDataItemDropRarity));
            harmony.PatchAll(typeof(AdventureDataItemDropNum));
            harmony.PatchAll(typeof(AdventureData_Rate));
         //   harmony.PatchAll(typeof(AdventureData_EarnByFloor));
//             harmony.PatchAll(typeof(AdventureDataMakeCurrentEnemyRank));
            harmony.PatchAll(typeof(AdventureDataGetDroppedRealItem));
//             harmony.PatchAll(typeof(AdventureDataMakeItemDropFloors));
        }
        [HarmonyPatch(typeof(NussygameCore), "GainExp")]
        class NussygameCoreGainExp{
            public static void Prefix(ref int val) {
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}]", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +"获得Exp "+val);
                val+=1000000;
            }
        }
        [HarmonyPatch(typeof(AdventureData), "ItemDropRarity")]
        class AdventureDataItemDropRarity{
            public static bool Prefix(AdventureData __instance, ref int __result) {
                __result=Mathf.Max(UnityEngine.Random.Range(48,60)/10, __instance.ItemDropRarityMax());
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +"ItemDropRarity="+__result);
                return false;
            }
        }
        [HarmonyPatch(typeof(AdventureData), "ItemDropNum")]
        class AdventureDataItemDropNum{
            public static bool Prefix(AdventureData __instance, ref int __result) {
                __result=1000;
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +"ItemDropNum="+__result);
                return false;
            }
        }
        class AdventureData_Rate{
            static IEnumerable<MethodBase> TargetMethods()
            {
                foreach(string str in new string[]{"RarityUpRate", "RuneDropRate", "UniqueDropRate", "UniqueDropRate", "CaptureDropRate"}){
                    MethodInfo m=typeof(AdventureData).GetMethod(str,(BindingFlags)(-1));
                    if(m!=null){
                        yield return m;
                    }
                }
            }
            public static bool Prefix(MethodBase __originalMethod, ref int __result) {
                __result=10000;
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +__originalMethod+"="+__result);
                return false;
            }
        }
        class AdventureData_EarnByFloor{
            static IEnumerable<MethodBase> TargetMethods()
            {
                foreach(string str in new string[]{"ExpEarnByFloor", "JunkEarnByFloor"}){
                    MethodInfo m=typeof(AdventureData).GetMethod(str,(BindingFlags)(-1));
                    if(m!=null){
                        yield return m;
                    }
                }
            }
            public static bool Prefix(MethodBase __originalMethod, ref int __result) {
                __result+=100;
                __result*=100;
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +__originalMethod+"="+__result);
                return false;
            }
        }

        [HarmonyPatch(typeof(AdventureData), "CurrentEnemyRank")]
        class AdventureDataMakeCurrentEnemyRank{
            public static void Postfix(AdventureData __instance, ref int __result) {
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +"CurrentEnemyRank="+__result.ToString());
                __result=1;
            }
        }
        [HarmonyPatch(typeof(AdventureData), "GetUniqueDropItemMaster")]
        class AdventureDataGetDroppedRealItem{
            public static void Prefix(ref bool ForceUniqueDrop) {
                logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
                    +"GetUniqueDropItemMaster="+ForceUniqueDrop.ToString());
                ForceUniqueDrop=true;
            }
        }
//         [HarmonyPatch(typeof(AdventureData), "MakeItemDropFloors")]
//         class AdventureDataMakeItemDropFloors{
//             public static void Postfix(AdventureData __instance, List<int> __result) {
//                 logger(string.Format("[{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}] ", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)
//                     +"MakeItemDropFloors="+__result.ToString());
//             }
//         }
    }
}
